linux内核中打印栈回溯信息 | 您所在的位置:网站首页 › rust 栈信息 › linux内核中打印栈回溯信息 |
简介
当内核出现比较严重的错误时,例如发生Oops错误或者内核认为系统运行状态异常,内核就会打印出当前进程的栈回溯信息,其中包含当前执行代码的位置以及相邻的指令、产生错误的原因、关键寄存器的值以及函数调用关系等信息,这些信息对于调试内核错误非常有用。 打印函数调用关系的函数就是dump_stack(),该函数不仅可以用在系统出问题的时候,我们在调试内核的时候,可以通过dump_stack()函数的打印信息更方便的了解内核代码执行流程。 dump_stack()函数的实现和系统结构紧密相关,本文介绍ARM体系中dump_stack()函数的实现。该函数定义在arch/arm/kernel/traps.c文件中,调用dump_stack()函数不需要添加头文件,基本上在内核代码任何地方都可以直接使用该函数。 相关基本知识读者需要了解一些ARM汇编的基本知识。在讲代码之前,我先简单说说内核中函数调用的一般过程。 关键寄存器介绍: 寄存器 含义 r0-r3 用作函数传参,例如函数A调用函数B,如果A需要向B传递参数,则将参数放到寄存器r0-r3中,如果参数个数大于4,则需要借用函数的栈空间。 r4-r11 变量寄存器,在函数中可以用来保存临时变量。 r9(SB) 静态基址寄存器。 r10(SL) 栈界限寄存器。 r11(FP) 帧指针寄存器,通常用来访问函数栈,帧指针指向函数栈中的某个位置。 r12(IP) 内部过程调用暂存寄存器。 r13(SP) 栈指针寄存器,用来指向函数栈的栈顶。 r14(LR) 链接寄存器,通常用来保存函数的返回地址。 r15(PC) 程序计数器,指向代码段中下一条将要执行的指令,不过由于流水线的作用,PC会指向将要执行的指令的下一条指令。 内核中的函数栈内核中,一个函数的代码最开始的指令都是如下形式: mov ip, sp stmfd sp!, {r0 - r3} (可选的) stmfd sp!, { ..., fp, ip, lr, pc} ……从其中两条stmfd(压栈)指令可以看出,一个函数的函数栈的栈底(高地址)的结构基本是固定的,如下图: |
CopyRight 2018-2019 实验室设备网 版权所有 |